/*********************************************************
*Copyright (c) 2015 zhongsx. All Rights in Pw 
*@des: 事件Timer 管理器
*@name: BEventTimer.cpp
*@author: zhongsx
*@time: 2015-02-14
*********************************************************/
#include "BEventTimer.h"


AsyncTimer::AsyncTimer(boost::asio::io_service& ios, int num,  CallFunc func, EndFunc endfc,int millsec):
		_func(func), _end(endfc), count_max(num), count(0),_millsec(millsec), _clock(""), 
		_timer(ios, boost::posix_time::millisec(millsec))
{
	if (count_max != 0){
		// 异步等待计时器  
		_timer.async_wait(boost::bind(&AsyncTimer::CallBack, this, _1)); // 注册回调函数  
	}
}

AsyncTimer::AsyncTimer(boost::asio::io_service& ios, int num, CallFunc func, EndFunc endfc, std::string clock): 
		_func(func), _end(endfc), count_max(num), count(0), _millsec(0), _clock(clock), 
		_timer(ios, boost::posix_time::millisec(getmillsec(clock)))
{
	if (count_max != 0){
		// 异步等待计时器 
		_timer.async_wait(boost::bind(&AsyncTimer::CallBack, this, _1)); // 注册回调函数  
	}
}

AsyncTimer::~AsyncTimer()
{
	_timer.cancel();
}

long AsyncTimer::getmillsec(std::string timing)
{	
	//当前时间
	boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
	//当前时间到0点的时间间隔
	boost::posix_time::time_duration now_clock = now.time_of_day();
	//clock 时间到0点的时间间隔
	boost::posix_time::time_duration time_clock(boost::posix_time::duration_from_string(timing));
	//
	boost::posix_time::time_duration last;
	if (now_clock < time_clock){
		last = time_clock - now_clock;
	}
	else{
		//获取今天
		boost::gregorian::date todayDate = now.date();
		boost::posix_time::ptime today(todayDate, now_clock);
		//获取明天
		boost::gregorian::date tomorrowDate = now.date() + boost::gregorian::date_duration(1);
		boost::posix_time::ptime tomorrow(tomorrowDate, time_clock);
		last = tomorrow - today;
	}
	return last.total_milliseconds();
}

//到时回调
void AsyncTimer::CallBack(const boost::system::error_code& ec)
{	
	if (ec){
		return;
	}

	//先调用事件
	count++;
	_func();
	//然后判断
	if ( count_max > 0 && count >= count_max){
		_end(this->shared_from_this()); //结束回调
		return;
	}

	// 重新设置定时器的终止时间  
    if (_clock == ""){
   	 	_timer.expires_at(_timer.expires_at() + boost::posix_time::millisec(_millsec));
    }
    else if (_millsec == 0){
    	_timer.expires_at(_timer.expires_at() + boost::posix_time::millisec(getmillsec(_clock)));	
    }
    // 异步等待计时器 
	_timer.async_wait(boost::bind(&AsyncTimer::CallBack, this, _1)); // 注册回调函数 
}


////////////////////////////////////////////////////////////////////////////
//
boost::shared_ptr<BEventTimer> BEventTimer::pEventTimer; 

BEventTimer::BEventTimer()
{

}

BEventTimer::~BEventTimer()
{

}

void BEventTimer::Run(boost::thread_group& group)
{
	// 增加一个work对象  
	boost::asio::io_service::work work(ios);  

	group.create_thread(boost::bind(&boost::asio::io_service::run, &ios));
}

//
void BEventTimer::EndCallBack(boost::shared_ptr<AsyncTimer>& timer)
{
	boost::mutex::scoped_lock lock(_mutex); 
	std::vector<boost::shared_ptr<AsyncTimer> >::iterator itr;

	for(itr = event_vec.begin(); itr != event_vec.end(); itr++){
		boost::shared_ptr<AsyncTimer> ptr(*(itr));
		if (ptr == timer){
			event_vec.erase(itr);
			break;
		}
	}
}

//
void BEventTimer::SetEventListener(CallFunc _func, int num, long _millsec)
{
	//int _microsec = get_microsec(_m);
	//boost::function<void(boost::shared_ptr<AsyncTimer>& )>
	EndFunc _end = boost::bind(&BEventTimer::EndCallBack, this, _1);
	boost::shared_ptr<AsyncTimer> ptrTimer(new AsyncTimer(ios, num, _func, _end, _millsec));
	event_vec.push_back(ptrTimer);
}

//
void BEventTimer::SetEventListener(CallFunc _func, int num, std::string _clock)
{
	EndFunc _end = boost::bind(&BEventTimer::EndCallBack, this, _1);
	boost::shared_ptr<AsyncTimer> ptrTimer(new AsyncTimer(ios, num, _func, _end, _clock));
	event_vec.push_back(ptrTimer);
}

boost::shared_ptr<BEventTimer>& BEventTimer::GetTimerInstance()
{
	if (!pEventTimer){
		pEventTimer = boost::shared_ptr<BEventTimer>(new BEventTimer());
	}
	return pEventTimer;
} 
